﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Serialization;

namespace NEMproject
{
    public class FormSerializer
    {

        public static IEnumerable<Control> GetAll(Control control, Type type)
        {
            var controls = control.Controls.Cast<Control>();

            return controls.SelectMany(ctrl => GetAll(ctrl, type))
                                      .Concat(controls)
                                      .Where(c => c.GetType() == type);
        }

        public static void LoadState(Form f, String path)
        {
            //Deserialize saved state
            StreamReader sr = new StreamReader(path);
            XmlSerializer xs = new XmlSerializer(typeof(StateOfForm));
            StateOfForm sf = (StateOfForm)xs.Deserialize(sr);

            //Find all controls of interest in the form and put the in a dictionary
            Dictionary<String, Control> controls = new Dictionary<String, Control>();
            IEnumerable<Control> formControls = GetAll(f, typeof(TextBox));
            formControls = formControls.Concat(GetAll(f, typeof(MaskedTextBox)));
            foreach (Control c in formControls)
            {
                controls.Add(c.Name, c);
            }

            //Iterate over the cofiguration file, identify the control and restore its value
            PropertyInfo pi;
            Type t;
            foreach (MyKeyValuePair pair in sf)
            {
                if (controls.ContainsKey(pair.Key))
                {
                    t = controls[pair.Key].GetType();
                    pi = t.GetProperty("Text");
                    pi.SetValue(controls[pair.Key], pair.Value, null);
                }
            }

        }

        public static void SaveState(Form f, String path)
        {
            //Extract state from the controls in the form
            StateOfForm state = new StateOfForm();
            IEnumerable<Control> controls = GetAll(f, typeof(TextBox));
            controls = controls.Concat(GetAll(f, typeof(MaskedTextBox)));
            foreach (Control c in controls)
            {
                state.Add(c.Name, c.Text);
            }
            //Serialize into XML
            XmlSerializer xs = new XmlSerializer(typeof(StateOfForm));
            StringBuilder sb = new StringBuilder();
            StringWriter sw = new StringWriter(sb);
            xs.Serialize(sw, state);
            System.IO.StreamWriter file = new System.IO.StreamWriter(path);
            file.WriteLine(sw);
            file.Close();
        }




        public class StateOfForm :
            List<MyKeyValuePair>
        {
            public void Add(string key, String value)
            {
                this.Add(
                    new MyKeyValuePair(key, value));
            }

            public String this[string key]
            {
                get
                {
                    foreach (var kvp in this)
                    {
                        if (key == kvp.Key) return kvp.Value;
                    }
                    throw new KeyNotFoundException();
                }
            }
        }
    }

    public class MyKeyValuePair
    {
        public String Key { get; set; }
        public String Value { get; set; }
        public MyKeyValuePair()
        {
        }
        public MyKeyValuePair(String key, String value)
        {
            this.Key = key;
            this.Value = value;
        }
    }
}
